home *** CD-ROM | disk | FTP | other *** search
- *****************************************************************************
- *** Point in Polygon Routine (c) November 1991 by McDeal/D-TECT ***
- *** Released in HACK-MAG Issue #7 ***
- *****************************************************************************
-
- ;With this routine you can test whether a point is within a convex polygon
- ;or not.
-
- ;This formula was used: C = (x2-x1)*(y-y1)-(y2-y1)*(x-x1)
- ;when C<0, then the point P(x,y) is left of the line (x1,y1,x2,y2)
- ;when C>0, then the point P(x,y) is right of the line (x1,y1,x2,y2)
-
- ;The result of this formula is only correct if your coordinate origin is
- ;in the upper left corner of the screen. If it is in the lower left corner
- ;you have to interprete the result the other way round...
-
- ;IMPORTANT NOTE: I didn't optimize anything of this example because I was
- ;in a BIG hurry! And I think it is much easier for beginners to understand
- ;source codes which aren't optimized... You know...
-
- ; signed: McDeal/D-TECT
-
- ;PS: GREEN means: Inside polygon.
- ; RED means: Outside polygon. Now start it!
-
- ;PPS: This is a Devpac Source Code!
-
- ***************************************************
- *** Constants Definition ***
- ***************************************************
-
- PlaneWidth = 40
- PlaneLen = PlaneWidth*256
- SpriteHigh = 1
- SpriteWidth = 16
-
- MouseClipX = 320-SpriteWidth+1
- MouseClipY = 256-SpriteHigh-5
-
- DL_MInterns = $ca
- SML = 0
-
- ***************************************************
- *** Program Start ***
- ***************************************************
-
- opt o+
-
- section a,code_c
-
- Start: lea $dff000,a5
-
- bsr DrawPolygon
- bsr.s InitInts
- bsr.s InitSprite
- bsr.s SetPlanePtr
- bsr StartCopper
- bsr Main
- bsr StopCopper
- bsr.s ReInitInts
-
- moveq #0,d0
- rts
-
- ***************************************************
- *** Init Interrupt ***
- ***************************************************
-
- InitInts: move.w $1c(a5),d0 ;Save INTENA
- bset #15,d0
- move.w d0,Interrupts
- move.w #$3fff,$9a(a5) ;turn off all Ints (INTENA)
- move.l $6c.w,Level3Int ;Save old Level 3 Int
- lea MouseRoutine(pc),a0 ;Set New Routine Ptr
- move.l a0,$6c.w
- move.w #$c020,$9a(a5) ;Permit Level 3 Int
- rts
-
- Interrupts: dc.w 0
- Level3Int: dc.l 0
-
- ***************************************************
- *** ReInit Interrupts ***
- ***************************************************
-
- ReInitInts: move.w #$3fff,$9a(a5) ;turn off all Ints (INTENA)
- move.l Level3Int(pc),$6c.w ;set old Level3Int Ptr
- move.w Interrupts(pc),$9a(a5) ;set old INTENA contents
- rts
-
- ***************************************************
- *** Init Sprite ***
- ***************************************************
-
- InitSprite: move.l #MouseSpr,d0 ;Sprite Structure Ptr
- lea MouseSprite(pc),a0 ;NCList Ptr
- move.w d0,6(a0) ;Set Ptr
- swap d0
- move.w d0,2(a0)
- rts
-
- ***************************************************
- *** Set Plane Ptr in Copperlist ***
- ***************************************************
-
- SetPlanePtr: lea PlanePtr(pc),a1
- move.l #Plane,d0
- move.w d0,6(a1) ;Low Word
- swap d0
- move.w d0,2(a1) ;High Word
- rts
-
- ***************************************************
- *** Start/Stop Copper ***
- ***************************************************
-
- StartCopper: move.w #$0380,$96(a5)
- move.l #NCList,$84(a5)
- clr.w $8a(a5)
- move.w #$83a0,$96(a5)
- clr.w $36(a5) ;Clear JOY0DAT
- rts
-
- StopCopper: move.w #$0380,$96(a5)
- clr.w $88(a5)
- move.w #$8380,$96(a5)
- rts
-
- ***************************************************
- *** Draw Polygon ***
- ***************************************************
-
- DrawPolygon: lea $dff002,a6
- lea Koords(pc),a2
- move.w (a2)+,d7 ;Number of Lines
-
- .DrawLineLoop: lea Plane,a0
- moveq #PlaneWidth,d4 ;This shitty loop isn't
- moveq #-1,d5 ;optimized!!! Don't blame me!
- movem.w (a2)+,d0-d3
-
- .WB: btst #6,(a6)
- bne.s .WB
- move.w d5,$44-$02(a6)
- move.w d5,$72-$02(a6)
- move.w #$8000,$74-$02(a6)
- move.w d4,$60-$02(a6)
- move.w d4,$66-$02(a6)
-
- bsr.s DrawLine
- dbf d7,.DrawLineLoop
- rts
-
- ***************************************************
- *** DrawLine ***
- ***************************************************
-
- ;Needs:
- ; a0 PlanePtr
- ; a6 $dff002
- ; d0/d1 x,y start pos
- ; d2/d3 x,y end pos
- ; d4 Width of plane
-
- ;Kills:
- ; d0-d4/a0-a1 (+d5 in Fill Mode)
-
- DrawLine: cmp.w d1,d3 ;drawing only from top to bottom is
- bge.s .y1ly2 ;necessary for:
- exg d0,d2 ;a: up-down differences (same koords)
- exg d1,d3 ;b: blitter invert bit (only at top of line)
-
- .y1ly2: sub.w d1,d3 ;d3:yd
-
- ;here we could do an optimization with special shifts
- ;depending on the PlaneWidth value ... i know it, but please, let it be.
-
- mulu d4,d1 ;use muls for neg y-vals
- add.l d1,a0 ;please don't use add.w here!
- moveq #0,d1 ;d1:quant-counter
- sub.w d0,d2 ;d2:xd
- bge.s .xdpos
- addq.w #2,d1 ;set bit 1 of quant-counter (here it could be a moveq)
- neg.w d2
- .xdpos: moveq #$f,d4 ;d4 full cleaned (for later oktants move.b)
- and.w d0,d4
- lsr.w #3,d0 ;yeah, on byte (necessary for bchg) ....
- add.w d0,a0 ;... blitter ands automagically
- ror.w #4,d4 ;4:shift
- or.w #$b00+DL_MInterns,d4 ;bltcon0-codes
- swap d4
- cmp.w d2,d3 ;which delta is the biggest?
- bge.s .dygdx
- addq.w #1,d1 ;set bit 0 of quant-counter
- exg d2,d3 ;exchange xd with yd
- .dygdx: add.w d2,d2 ;d2:xd*2
- move.w d2,d0 ;d0:save for $52(a6)
- sub.w d3,d0 ;d0:xd*2-yd
- addx.w d1,d1 ;Bit0:sign-bit
- move.b .oktants(pc,d1.w),d4 ;in low byte of d4 (upper byte cleaned above)
- swap d2
- move.w d0,d2
- sub.w d3,d2 ;d2:2*(xd-yd)
- moveq #6,d1 ;d1:shiftval(not necessary) + testval for the blitter
- lsl.w d1,d3 ;d3:BLTSIZE
- add.w #$42,d3
- lea $52-2(a6),a1 ;a1:CUSTOM + $52
-
- ;WARNING: if you use fastmem and an extreme DMA-Access (e.g. 6
- ;planes and copper), you should insert a tst.b (a6) here (for the
- ;shitty AGNUS-BUG).
-
- .WB: btst d1,(a6) ;waiting for the blitter ...
- bne.s .WB
-
- move.l d4,$40-2(a6) ;writing to the blitter regs as fast as possible.
- move.l d2,$62-2(a6)
- move.l a0,$48-2(a6)
- move.w d0,(a1)+
- move.l a0,(a1)+ ;shit-word buffer pt.
- move.w d3,(a1)
- rts
-
- ; ------------- oktant-table --------------------------------------------
-
- .oktants: dc.b SML+1,SML+1+$40
- dc.b SML+17,SML+17+$40
- dc.b SML+9,SML+9+$40
- dc.b SML+21,SML+21+$40
-
- ***************************************************
- *** Main Loop ***
- ***************************************************
-
- Main: move.l $04(a5),d0
- and.l #$1ff00,d0
- cmp.l #150*256,d0
- bne.s Main
-
- .Wait: move.l $04(a5),d0
- and.l #$1ff00,d0
- cmp.l #151*256,d0
- bne.s .Wait
-
- bsr.s TestMousePos ;This is the MAIN routine!
-
- btst #6,$bfe001
- bne.s Main
-
- .WB: btst #6,2(a5)
- bne.s .WB
- rts
-
- ***************************************************
- *** Test Mouse Pos ***
- ***************************************************
-
- TestMousePos: lea Koords(pc),a0 ;Polygon Ptr
- movem.w MousePos(pc),d4-d5 ;X,Y Coord of Point
- bsr.s PointInPolygon
- tst.w d0 ;Test Flag
- beq.s .InPolygon ;if d0 = 0 -> inside!
-
- .Beep: move.w #$f00,$dff180 ;Point outside polygon
- rts
-
- .InPolygon: move.w #$0f0,$dff180 ;Point inside polygon
- .Exit: rts
-
- ***************************************************
- *** Point in Polygon Routine ***
- ***************************************************
-
- ;a0 = Ptr on Polygon Coordinate Lis (Polygon Clockwise!)
- ;d4 = X-Coord of point
- ;d5 = Y-Coord of point
- ;-> d0 <> 0 when point outside; d0 = 0 when point inside
-
- PointInPolygon: move.w (a0)+,d7 ;Amount of polygon lines-1
-
- .PolygonLoop: movem.w (a0)+,d0-d3 ;Get Line Coords
-
- sub.w d0,d2 ;(x2-x1)
- move.w d5,d6 ;save y
- sub.w d1,d6 ;(y-y1)
- muls d6,d2 ;(y-y1)*(x2-x1)
-
- sub.w d1,d3 ;(y2-y1)
- move.w d4,d6 ;save x
- sub.w d0,d6 ;(x-x1)
- muls d6,d3 ;(y2-y1)*(x-x1)
-
- sub.l d3,d2 ;(y-y1)*(x2-x1)-(y2-y1)*(x-x1)
- bmi.s .OutOfPolygon ;if neg-> outside
-
- dbf d7,.PolygonLoop
- moveq #0,d0 ;set inside-flag
- rts
-
- .OutOfPolygon: moveq #-1,d0 ;set outside-flag
- rts
-
- *** Polygon Structure ***
-
- Koords: dc.w 5-1 ;Polygon with 5 lines
- dc.w 55,1,100,30 ;1. lines
- dc.w 100,30,80,90 ;2. lines
- dc.w 80,90,20,80 ;3. lines
- dc.w 20,80,10,30 ;4. lines
- dc.w 10,30,55,1 ;5. lines
-
- ***************************************************
- *** Level3Int (Mouse-Routine) ***
- ***************************************************
-
- MouseRoutine: movem.l d0-d4/a0/a5,-(sp)
-
- lea $dff000,a5
- btst #5,$1e+1(a5) ;VBI ? (INTREQR+1)
- beq.s .Exit ;no-> Exit
-
- move.w #$0020,$9c(a5) ;Clear VBI Bit
-
- lea MousePos(pc),a0
- move.w (a0)+,d0
- move.w (a0)+,d1
- move.w $0a(a5),d2
- move.w d2,d3
- sub.b 1(a0),d2
- move.b d2,d4
- ror.w #8,d2
- sub.b (a0),d2
- move.w d3,(a0)
- ext.w d4
- add.w d4,d0
- bgt.s .Right
- moveq #0,d0
- bra.s .Up
- .Right: cmp.w #MouseClipX,d0
- blt.s .Up
- move.w #MouseClipX,d0
-
- .Up: ext.w d2
- add.w d2,d1
- bgt.s .Down
- moveq #0,d1
- bra.s .SetSpr
- .Down: cmp.w #MouseClipY,d1
- blt.s .SetSpr
- move.w #MouseClipY,d1
-
- ;\
- ; >- Now set the Sprite
- ;/
-
- .SetSpr: movem.w d0-d1,-(a0) ;Set X,Y
- lea MouseSpr(pc),a0 ;Sprite Structure Ptr
- add.w #128,d0
- add.w #42,d1
- move.w d1,d3
- addq.w #SpriteHigh,d3
- moveq #0,d4
- lsl.w #8,d1
- addx.b d4,d4
- lsl.w #8,d3
- addx.b d4,d4
- or.w d4,d3
- lsr.w #1,d0
- addx.b d3,d3
- or.w d0,d1
- move.w d1,(a0)+
- move.w d3,(a0)
- .Exit: movem.l (sp)+,d0-d4/a0/a5
- rte
-
- MousePos: dc.w 0,0 ; Don't change the order!
- OldMove: dc.w 0 ;/
-
- ***************************************************
- *** Datas ***
- ***************************************************
-
- NCList:
- MouseSprite: dc.l $01200000,$01220000,$01240000,$01260000
- dc.l $01280000,$012a0000,$012c0000,$012e0000
- dc.l $01300000,$01320000,$01340000,$01360000
- dc.l $01380000,$013a0000,$013c0000,$013e0000
-
- dc.l $008e2981,$009029c1,$00920038,$009400d0
- dc.l $01020000,$01040000,$01080000,$010a0000
- dc.l $01000200,$01a20ff0
-
- PlanePtr: dc.l $00e00000,$00e20000
- dc.l $01001200
-
- dc.l $01800000,$018200ff
- dc.l -2
-
- MouseSpr: dc.w 0,0
- dc.w $8000,$0000
- dc.w 0,0
-
- ***************************************************
- *** BSS Data Segment ***
- ***************************************************
-
- section b,bss_c
-
- Plane: ds.b PlaneLen
-
- END
-
-